package com.study.sbsummary.context;

import com.study.sbsummary.model.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.ConstraintViolationException;

/**
 * Controller 的统一异常处理
 *
 * @Author wangchao3@yidian-inc.com
 * @Date 2020-03-16 14:34
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {

	@ExceptionHandler(Throwable.class)
	@ResponseBody
	Response handleException(Throwable e) {
		log.error(e.getMessage(), e);
		if (e instanceof BizException) {
			return Response.failed(e.getMessage(), null);
		}
		else if (e instanceof HttpMessageNotReadableException) {
			return Response.failed("请求参数格式不正确", e.getMessage());
		} else if (e instanceof MethodArgumentNotValidException) {
			return Response.failed(getValidMsg((MethodArgumentNotValidException) e), e.getMessage());
		} else if (e instanceof ConstraintViolationException) {
            String originParam = getConstraintViolationMsg((ConstraintViolationException) e);
			log.error("参数错误 {}",e.getMessage() + originParam);
            return Response.failed("参数错误", e.getMessage() + originParam);
        } else {
			return Response.failed("系统错误", e.getMessage());
		}
	}

    private String getConstraintViolationMsg(ConstraintViolationException e) {
        StringBuilder sb = new StringBuilder();
        sb.append(": [");
        try {
            e.getConstraintViolations().forEach(violate -> sb.append(violate.getInvalidValue()));
        }catch (Exception ex){
            log.error("获取参数异常 {}",ex.getMessage());
        }
        sb.append("]");
        return sb.toString();
    }

    private String getValidMsg(MethodArgumentNotValidException e) {
		if (!e.getBindingResult().hasErrors()) {
			return "未知错误";
		}

		StringBuilder sb = new StringBuilder();
		for (ObjectError error : e.getBindingResult().getAllErrors()) {
			sb.append("|" + error.getDefaultMessage());
		}
		if (sb.length() > 0) {
			sb.delete(0, 1);
		}
		return sb.toString();
	}
}
